package main

import (
  "net"
  "strings"
)

type User struct {
  Name string 
  Addr string
  C chan string
  conn net.Conn

  //
  server *Server
}

//api:creat
func NewUser(conn net.Conn, server *Server) *User {
  userAddr := conn.RemoteAddr().String()

  user := &User{
    Name: userAddr,
    Addr: userAddr,
    C: make(chan string),
    conn: conn,

    server: server,
  }

  // 
  go user.ListenMessage()

  return user
}

//listen User channel
func (this *User) ListenMessage() {
  for {
    msg := <-this.C

    this.conn.Write([]byte(msg + "\n"))
  }
}

func (this *User) Online(){
  // add user to online map 
  this.server.mapLock.Lock()
  this.server.OnlineMap[this.Name] = this
  this.server.mapLock.Unlock()

  // broadcast this user has online
  this.server.Broadcast(this, "online.")

}
func (this *User) Offline(){
  // add user to online map 
  this.server.mapLock.Lock()
  delete( this.server.OnlineMap, this.Name)
  this.server.mapLock.Unlock()

  // broadcast this user has online
  this.server.Broadcast(this, "Offline.")

}

func (this *User) SendMsg(msg string){
  this.conn.Write([]byte(msg))
}

func (this *User) DoMessage(msg string){
  if msg == "who" {
    //return online users
    this.server.mapLock.Lock()
    for _,user := range this.server.OnlineMap{
      msg := "[" + user.Addr + "]" + user.Name + ":" + "online...\n"
      this.SendMsg(msg)
    }
    this.server.mapLock.Unlock()
  }else if len(msg)>7 && msg[:7] == "rename|"{
    // rename|newname
    newName := strings.Split(msg,"|")[1]
    // check exits?
    _, ok := this.server.OnlineMap[newName]
    if ok {
      this.SendMsg("user name has exits! try a new name.\n")
    }else{
      this.server.mapLock.Lock()

      delete(this.server.OnlineMap, this.Name)
      this.server.OnlineMap[newName] = this

      this.server.mapLock.Unlock()

      this.Name = newName
      this.SendMsg(this.Name + " has updated.\n")
    }
  } else if len(msg)>4 && msg[:3] == "to|"{
    args := strings.Split(msg,"|")
    remoteName := args[1]
    if remoteName == "" {
      this.SendMsg("format: \"to|xh|I am touyu.\" \n")
      return
    }
    remoteUser, ok := this.server.OnlineMap[remoteName]
    if !ok {
      this.SendMsg(remoteName+" is not exits.")
      return
    }
    content := args[2]
    if content == ""{
      this.SendMsg("please resend, empty message content.\n")
      return
    }

    remoteUser.SendMsg(this.Name + " say: " + content + "\n")
  } else{
    this.server.Broadcast(this, msg)
  }
}
